#
#	genx_extensions.py
#
#	David Janes
#	2008.08.16
#
#	GenX - search, create and insert structured data
#

import sys
import types
import re
import pprint
import cgi
import md5
import imp
import os
import os.path
import traceback

import genx_cfg
import genx_helpers
import bm_text
import bm_extract

from bm_log import Log

def load_module(code_path):
	try:
		try:
			code_dir = os.path.dirname(code_path)
			code_file = os.path.basename(code_path)

			fio = open(code_path, 'rb')

			return	imp.load_source(md5.new(code_path).hexdigest(), code_path, fio)
		finally:
			try: fio.close()
			except: pass
	except IOError:
		Log("IO error importing module", exception = True, code_path = code_path)
		return	None
	except ImportError, x:
		Log("module does not exist", exception = True, code_path = code_path)
		return	None
	except:
		Log("module error", exception = True, code_path = code_path)
		return	None

class ExtensionsMixin:
	"""This Mixin loads all the extensions -- i.e. the mashup code -- in 'self.searchds'

	Extensions are stored on disk as follows:

	GENX_ROOT
	  extensions
	    <extension_name>
		  query.py -- the active code
		  form.js -- the InputEx form for displaying a single entry
		  <template_name> 
		    html.t -- the standard *required* template
			gencard.t -- the "GenCard" template
			<other>.t -- other possible templates
	"""

	def __init__(self):
		self.FindExtensions()

	def FindExtensions(self):
		extensions_dir = os.path.join(genx_cfg.cfg["home_path"], "extensions")
		for mid in os.listdir(extensions_dir):
			module_dir = os.path.join(extensions_dir, mid)
			module_path = os.path.join(module_dir, "query.py")
			module = load_module(module_path)
			if not module:
				continue

			#
			#
			#
			ok = True
			for required in [ 'searchd', 'query', ]:
				if not hasattr(module, "searchd"):
					print >> sys.stderr, "module '%s' does not have '%s' -- skipping" % ( module_path, required, )
					ok = False
					break

			if not ok:
				continue

			#
			#	Find all the templates -- templates will exist
			#	in subdirectories and will have extension ".t"
			#
			module.templateds = []

			for dir in os.listdir(module_dir):
				template_dir = os.path.join(module_dir, dir)

				if dir.startswith(".") or not os.path.isdir(template_dir):
					continue

				#
				#	Fill in basic information, extending if possible with
				#	information defined in the module
				#
				templates = {}
				templated = {
					"tid" : dir,
					"title" : dir,
					"title_full" : dir,
					"caps" : genx_helpers.CAP_HTML,
					"templates" : templates,
				}

				d = bm_extract.extract(module.searchd, 'templated.%s' % dir)
				if d and type(d) == types.DictType:
					templated.update(d)

				#
				#	Look for templates
				#
				for file in os.listdir(template_dir):
					if file.startswith(".") or not file.endswith(".t"):
						continue

					template_name = file[:-2]

					try:
						try:
							template_path = os.path.join(template_dir, file)
							fio = open(template_path)
							templates[template_name] = fio.read()
						finally:
							try: fio.close()
							except: pass
					except IOError:
						traceback.print_exc(file = sys.stderr)
						continue

				if templates:
					module.templateds.append(templated)

			#
			#
			#
			module.searchd['mid'] = mid
			module.searchd['module'] = module

			self.searchds.append(module.searchd)
			self.searchdd[mid] = module.searchd

		self.searchds.sort(lambda ad, bd: cmp(ad.get('title'), bd.get('title')))
